using System;
using System.Collections.Generic;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    [TestFixture]
    public class TestDMRelationshipPropertyTypesAreSame
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #region TestDMRelationshipPropertyTypesAreSame

        //At least one side of the relationship must be a PK or AK
        //Single-to-single must be PK to AK(FK)

        [Test]
        public void Test_CreateDMRelationshipPropertyTypesAreSameRule()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            //---------------Assert Precondition----------------
            Assert.IsNotNull(relationshipProperty);
            IDMRelationshipProperty reverseRelationshipProperty = relationshipProperty.ReverseRelationshipProperty;
            Assert.IsNotNull(reverseRelationshipProperty);
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Test Result -----------------------
            Assert.IsNotNull(rule);
            Assert.AreEqual("DMRelationshipPropertyTypesAreSame", rule.Name);
            Assert.AreEqual(ErrorLevel.Warning, rule.ErrorLevel);
        }

//        [Test]
//        public void Test_CreateDMRelationshipPropertyTypesAreSameRule_WhenRelationshipPropertyNull_ShouldRaiseError()
//        {
//            //---------------Set up test pack-------------------
//            //---------------Assert Precondition----------------
//            //---------------Execute Test ----------------------
//            try
//            {
//                new DMRelationshipPropertyTypesAreSame(null);
//                Assert.Fail("expected ArgumentNullException");
//            }
//            //---------------Test Result -----------------------
//            catch (ArgumentNullException ex)
//            {
//                StringAssert.Contains("Value cannot be null", ex.Message);
//                StringAssert.Contains("relationshipProp", ex.ParamName);
//            }
//        }

        [Test]
        public void Test_IsValid_WhenNoProperty_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            relationshipProperty.Property = null;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNull(relationshipProperty.Property);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenNoPropertyType_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            relationshipProperty.Property.PropertyType = null;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNull(relationshipProperty.Property.PropertyType);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenNoReverseRelationshipProp_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            relationshipProperty.ReverseRelationshipProperty = null;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNull(relationshipProperty.ReverseRelationshipProperty);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenReverseRelationshipPropHasNoProperty_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            relationshipProperty.ReverseRelationshipProperty.Property = null;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNull(relationshipProperty.ReverseRelationshipProperty.Property);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenReverseRelationshipProp_PropertyHasNoPropertyType_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            relationshipProperty.ReverseRelationshipProperty.Property.PropertyType = null;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNull(relationshipProperty.ReverseRelationshipProperty.Property.PropertyType);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenPropertyTypesAreSame_ShouldPass()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            IDMRelationshipProperty reverseRelationshipProperty = relationshipProperty.ReverseRelationshipProperty;
            relationshipProperty.Property.PropertyType = reverseRelationshipProperty.Property.PropertyType;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(relationshipProperty.Property.PropertyType);
            Assert.AreSame(relationshipProperty.Property.PropertyType, reverseRelationshipProperty.Property.PropertyType);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenPropertyTypesAreNotSame_ShouldFail()
        {
            //---------------Set up test pack-------------------
            DMRelationship dmRelationship = TestUtilsShared.CreateUnsavedRelationshipInfoWithTwoRelatedProperties();
            DMRelationshipProperty relationshipProperty = dmRelationship.RelationshipProperties[0];
            IDMRelationshipProperty reverseRelationshipProperty = relationshipProperty.ReverseRelationshipProperty;
            DMSolution dmSolution = (DMSolution) dmRelationship.ClassDM.Solution;
            DMPropertyType newPropType = dmSolution.PropertyTypes.CreateBusinessObject();
            newPropType.AssemblyName = TestUtilsShared.GetRandomString();
            newPropType.PropertyTypeName = TestUtilsShared.GetRandomString();
            relationshipProperty.Property.PropertyType = dmSolution.GetDMPropertyType("System", "String");
            reverseRelationshipProperty.Property.PropertyType = newPropType;
            IBusinessObjectRule rule = new DMRelationshipPropertyTypesAreSame();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(relationshipProperty.Property.PropertyType);
            Assert.IsNotNull(reverseRelationshipProperty.Property.PropertyType);
            Assert.AreNotSame(relationshipProperty.Property.PropertyType, reverseRelationshipProperty.Property.PropertyType);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(relationshipProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
            StringAssert.Contains("Relationship Property '" + relationshipProperty, rule.Message);
            StringAssert.Contains("' property type('" + relationshipProperty.Property.PropertyTypeString + "') is not the same ", rule.Message);
            StringAssert.Contains("as its Related Relationship Property '" + reverseRelationshipProperty + "'", rule.Message);
            StringAssert.Contains("' property type('" + reverseRelationshipProperty.Property.PropertyTypeString + "')", rule.Message);
        }
        #endregion
    }

}